package org.shangrila.app.wechat.service;

import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.enterprise.context.SessionScoped;
import javax.faces.FacesException;
import javax.servlet.http.HttpServletRequest;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.ExcessiveAttemptsException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.primefaces.model.menu.DefaultMenuItem;
import org.primefaces.model.menu.DefaultMenuModel;
import org.primefaces.model.menu.DefaultSubMenu;
import org.primefaces.model.menu.MenuModel;
import org.shangrila.app.sys.dao.SysDao;
import org.shangrila.app.sys.eo.SysAuthority;
import org.shangrila.app.sys.eo.SysLogin;
import org.shangrila.app.sys.eo.SysMenus;
import org.shangrila.app.sys.eo.SysResource;
import org.shangrila.app.sys.eo.SysUser;
import org.shangrila.app.wechat.bean.WxError;
import org.shangrila.app.wechat.constant.WechatApiUrl;
import org.shangrila.app.wechat.notification.TextMessage;
import org.shangrila.app.wechat.notification.TextMessageChild;
import org.shangrila.app.wechat.utils.AccessWxUtil;
import org.shangrila.app.wechat.utils.JSONObjectUtil;
import org.shangrila.app.wechat.utils.MessageUtil;
import org.shangrila.app.wechat.utils.WeChatHttpUtil;
import org.shangrila.app.wechat.utils.WeChatUtil;
import org.shangrila.comm.helper.IDHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

import com.google.gson.JsonObject;

@Controller
@Component
@SessionScoped
@RequestMapping("/wechat")
public class HomeController {
	private Logger logger = LoggerFactory.getLogger(HomeController.class);
	private String loginPage = "/pages/login.jsf?faces-redirect=true";
	/**
	 * /pages/mhome.jsf?faces-redirect=true 找不到页面，只能用下面这种做重定向，未知原因，上面login是可以的
	 */
	private String homePage = "http://18802014406.tunnel.qydev.com/bmepp/pages/mobile/home_mb.xhtml";
	//private String homePage = "http://124.115.22.152:8080/bmepp/pages/mobile/home_mobile.xhtml?faces-redirect=true";
	
	private SysUser user;
	private String userId;
	
	
	private String ipaddress;
	private SysUser operatorUser;
	private MenuModel model;
	
	private boolean loginFlag; // 标识用户是否已经登录，用于安全访问判断

	@RequestMapping("")
	public String index() {
		String  tokenUrl=WechatApiUrl.GET_USER_CODE
				.replace("CORPID",AccessWxUtil.appid)
				.replace("REDIRECT_URI",URLEncoder.encode("http://18802014406.tunnel.qydev.com/bmepp/wechat/wechatLogin"))//授权成功回调页面,测试时默认会调用两次
				.replace("SCOPE","snsapi_userinfo")
				.replace("AGENTID",AccessWxUtil.agentid)
				.replace("STATE","state"+System.currentTimeMillis());
		logger.error(tokenUrl);
		return "redirect:"+tokenUrl;
	}
	
	
	@RequestMapping("/wechatLogin")
	public String getCode(@RequestParam(name="code",required=false)String code,
            @RequestParam(name="state")String state,HttpServletRequest request) {
		
		JsonObject jsonObject = WeChatHttpUtil.getUserInfoByCode(code);
		String userid = JSONObjectUtil.getAsString(jsonObject, "UserId");
		if(userid!=null&&!userid.isEmpty()) {
			//测试时回调，默认会调用两次，导致第二次使用code会失效，userId会返回为空，所以当userId为空时跳过，（可能由于二级域名问题18802014406.tunnel.qydev.com）
			userId = userid;
		}
		
		if(!userId.isEmpty()) {
			try{
				user = null;
				SysDao sysdao = new SysDao();
				user = sysdao.findSysUserByWxno(userId);
				if(user!=null) {
					logger.error("userno------------------"+user.getUserno());
				}
			}catch(Exception e){			
			}
		}else {
			user = null;
		}
		
		ipaddress = request.getRemoteAddr();
		SecurityUtils.getSubject().getSession().setAttribute("userId", userId);
		AccessWxUtil.wxUserId = userId;
		
		if(user==null) {
			return loginPage;
		}else {
			logger.error("userno--"+user.getUserno()+"---userPassword----"+user.getPassword());
			if(logins()) {
				initMenuInfo();
				recordLoginInfo();
				logger.error(homePage);
				return "redirect:"+homePage;
				}else {
					logger.error("null");
					return null;
				}
				
		}
	}
	
	public boolean logins() throws FacesException {
		
		Subject subject = SecurityUtils.getSubject();
		UsernamePasswordToken token = new UsernamePasswordToken(user.getUserno(),user.getPassword());
		try {			
			token.setRememberMe(true);
			subject.login(token);

			loginFlag = true;
			operatorUser = (SysUser)SecurityUtils.getSubject().getSession().getAttribute("shiroUser");			
			// 取得当前loginFlag:"Y"
			String flag = (String)SecurityUtils.getSubject().getSession().getAttribute("loginFlag");	
			logger.info("loginFlag:"+flag);
			
			return loginFlag;

		} catch  ( ExcessiveAttemptsException eae ) { 
			token.clear();
			//MsgsUtil.showMessages("登录失败",	"超过三次尝试，不能登陆。");
			return loginFlag;
		} catch (UnknownAccountException ue) {
			token.clear();
			//MsgsUtil.showMessages("登录失败",	"输入的账号不存在");
			return loginFlag;
		} catch (IncorrectCredentialsException ie) {
			token.clear();
			//MsgsUtil.showMessages("登录失败",	"账号密码不匹配");
			return loginFlag;
		} catch (LockedAccountException lae) {
			//MsgsUtil.showMessages("登录失败",	"账号锁定");
			return loginFlag;
		} catch (AuthenticationException ae) {
			//MsgsUtil.showMessages("登录失败",	"认证错误");
			return loginFlag;
		} catch (RuntimeException re) {
			token.clear();
			//infostr = MsgsUtil.showMsgsInfo("info","MesShiroLoginValidate_login_runtime_error");
			//MsgsUtil.showMessages("登录失败",	"认证错误");
			return loginFlag;
		}
		
	}
	
	public void initMenuInfo() {

		SysDao sysdao = new SysDao();
		List<SysMenus> menuItems = sysdao.findSysMenuItems();//获取全部菜项信息 ID!=PID		
		List<SysMenus> menus = sysdao.findSysMenus(); //获取菜单（下面包含菜单项）ID=PID--->SubMenu
		
		List<SysMenus> validMenuItems  = new ArrayList<SysMenus>();//当前用户有效菜单项
		List<SysMenus> validMenus = new ArrayList<SysMenus>(); //当前用户有效菜单
				
		//过滤operatorUser的菜单项信息
		for (SysMenus ma : menuItems) {
			for (SysAuthority oa : operatorUser.getSysAuthorities()) {
				if(oa.getId() == ma.getSysAuthority().getId()){
					validMenuItems.add(ma);
				}
			}
		}
		//过滤operatorUser的菜单信息
		for (SysMenus ob : menus) {
			boolean flag = true;
			for (SysMenus mb : validMenuItems) {
				if( ob.getId() == mb.getPid()){
					flag = true;
					break;				
				}
				else
					flag = false;
			}
			if(flag) validMenus.add(ob);
		}

		model = new DefaultMenuModel();

		for (SysMenus m : validMenus) {//循环菜单
			DefaultSubMenu submenu = new DefaultSubMenu(m.getName());
			for (SysMenus mi : validMenuItems) {//循环菜单项
				if ( m.getId() == mi.getPid() ) {//如果菜单记录的PID与菜单的ID相等的是菜单项
					DefaultMenuItem item = new DefaultMenuItem(mi.getName());
					for (SysResource r : mi.getSysAuthority().getSysResources()) {//获取菜单项的URL和ICON
						if ("1".equalsIgnoreCase(r.getCategory())) {
							item.setUrl(r.getSource());
							item.setIcon(r.getIcon());
						}
					}
					submenu.addElement(item);
					}
			}
			model.addElement(submenu);
		}
	}
	
	public void recordLoginInfo(){
		
		SysLogin slog = new SysLogin();
		
		slog.setId(IDHelper.genNumID());
		slog.setLoginTime(new Date());
		slog.setUserno(user.getUserno());
		slog.setIpaddress(ipaddress);
		SysDao sysdao = new SysDao();
		try {
			sysdao.dbAccess.beginTransaction();
			sysdao.dbAccess.insert(slog);
			sysdao.dbAccess.commitTransaction();
		}catch(Exception e) {
			try{
				sysdao.dbAccess.rollback();
				}catch(Exception ex) {};
		}
		sysdao = null;
	}
}
